package ua.yandex.shad.tempseries;

import java.util.ArrayList;
import java.util.List;

public class TemperatureSeriesAnalysis {
    
    private final double[] temperatureSeries;
    
    class IllegalTemperatureValueException extends Exception {
        
        public IllegalTemperatureValueException() {}
        
        public IllegalTemperatureValueException(String msg) {
            super(msg);
        }
    } 

    public TemperatureSeriesAnalysis(double[] temperatureSeries) throws 
            IllegalTemperatureValueException {
        for(int i = 0; i < temperatureSeries.length; i++) {
            if(temperatureSeries[i] < -273) {
                throw new IllegalTemperatureValueException("The temperature "
                        + "can't be less than -273 C");
            }
        }
        this.temperatureSeries = temperatureSeries;
    }
    
    public double calcAverageTemp(){
        if(temperatureSeries == null || temperatureSeries.length == 0) return 0;
        
        double average = 0;
        for(int i = 0; i < temperatureSeries.length; i++) {
            average += temperatureSeries[i];
        }
        return average/temperatureSeries.length;
    }    
    
    public double calcTempDeviation(){
        if(temperatureSeries == null || temperatureSeries.length == 0) return 0;
        
        double dev = 0;
        for(int i = 0; i < temperatureSeries.length; i++) {
            dev += Math.pow(temperatureSeries[i], 2);
        }
        dev /= temperatureSeries.length;
        dev -= Math.pow(calcAverageTemp(), 2);
        return dev;
    }
    
    public double findTempClosestToZero(){
        if(temperatureSeries == null || temperatureSeries.length == 0) return 0;
        
        double zergood = temperatureSeries[0];
        for(int i = 1; i < temperatureSeries.length; i++) {
            if(Math.abs(temperatureSeries[i]) < Math.abs(zergood) || 
                    temperatureSeries[i] > 0 && temperatureSeries[i] == -zergood) {
                zergood = temperatureSeries[i];
            }
        }
        return zergood;
    }
    
    public double findTempClosestToValue(double tempValue) {
        if(temperatureSeries == null || temperatureSeries.length == 0) return 0;
        
        double valgood = temperatureSeries[0];
        for(int i = 1; i < temperatureSeries.length; i++) {
            if(Math.abs(tempValue - temperatureSeries[i]) < Math.abs(tempValue 
                    - valgood) || temperatureSeries[i] > 0 && valgood ==
                            -temperatureSeries[i]) {
                valgood = temperatureSeries[i];
            }
        }
        return valgood;
        
    }
    
    public double[] findTempsLessThen(double tempValue) {
        if(temperatureSeries == null) return null;
        
        List<Double> temp = new ArrayList<>();
        
        for(int i = 0; i < temperatureSeries.length; i++) {
            if(temperatureSeries[i] < tempValue) {
                temp.add(temperatureSeries[i]);
            }
        }
        double[] tempsLessThen = new double[temp.size()];
        for(int i = 0; i < temp.size(); i++) {
            tempsLessThen[i] = temp.get(i);
        }
        return tempsLessThen;
    }
    
    public double[] findTempsGreaterThen(double tempValue) {
        if(temperatureSeries == null) return null;
        
        List<Double> temp = new ArrayList<>();
        
        for(int i = 0; i < temperatureSeries.length; i++) {
            if(temperatureSeries[i] > tempValue) {
                temp.add(temperatureSeries[i]);
            }
        }
        double[] tempsGreaterThen = new double[temp.size()];
        for(int i = 0; i < temp.size(); i++) {
            tempsGreaterThen[i] = temp.get(i);
        }
        return tempsGreaterThen;
    }
}